package com.rankeiot.platform.service;

import cn.hutool.core.lang.Validator;
//import com.aliyun.dysmsapi20170525.Client;
//import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
//import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
//import com.aliyun.teaopenapi.models.Config;
//import com.aliyun.teautil.models.RuntimeOptions;

import com.aliyuncs.v5.CommonRequest;
import com.aliyuncs.v5.CommonResponse;
import com.aliyuncs.v5.DefaultAcsClient;
import com.aliyuncs.v5.IAcsClient;
import com.aliyuncs.v5.exceptions.ClientException;
import com.aliyuncs.v5.http.MethodType;
import com.aliyuncs.v5.profile.DefaultProfile;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.rankeiot.core.Current;
import com.rankeiot.core.data.UserInfo;
import com.rankeiot.core.data.response.Resp;
import com.rankeiot.core.sqltoy.TableUtil;
import com.rankeiot.core.util.JSONUtil;
import com.rankeiot.core.util.StringUtil;
import com.rankeiot.platform.config.SmsConfigs;
import com.rankeiot.platform.domain.ISmsTemplate;
import com.rankeiot.platform.domain.SmsMessage;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.sagacity.sqltoy.model.Page;
import org.sagacity.sqltoy.model.TableMeta;

import java.util.*;

@Slf4j
public class SmsService {
    SqlToyLazyDao dao;
    @Resource
    public void init(SqlToyLazyDao dao) {
        this.dao = dao;
        try {
            List<TableMeta> tm = dao.getTables(null, null, SmsMessage.TABLE);
            if (tm.size() == 0) {
                //初始化表
                TableUtil.createTable(dao, SmsMessage.class);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    private static Client createClient() throws Exception {
//        Map<String, String> configMap = CollectionUtil.toMap(SmsConfigs.values(), SmsConfigs::name, SmsConfigs::strValue);
//        Config config = Config.build(configMap);
//        return new Client(config);
//    }

    public void sendMessage(ISmsTemplate template, String phoneNumber, Object templateParam) {
        sendMessage(template.getSignName(), phoneNumber, template.getCode(), templateParam);
    }
    public static void sendSMS(String accessId,String secretKey,String signName,  String templateCode,String phoneNumber, Object templateParam){
        DefaultProfile profile= DefaultProfile.getProfile("cn-hangzhou", accessId,secretKey);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");

        request.setSysAction("SendSms");

        request.putQueryParameter("PhoneNumbers", phoneNumber);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", JSONUtil.toJSONString(templateParam));
        try{
            CommonResponse response = client.getCommonResponse(request);
            String rep= response.getData();
            Map<String,String> ret= JSONUtil.parseObject(rep);
            if (!"OK".equalsIgnoreCase(ret.get("Code"))) {
                log.error("sendSmsResponse:" + ret.get("Code")+ret.get("Message"));
                //错误code文档:https://help.aliyun.com/document_detail/101346.html?spm=api-workbench.API%20Explorer.0.0.1d3b6aa2EfsI8V
                if(ret.get("Message").contains("Permits")){
                    Resp.fail("短息发送达到上限，请稍后再试");
                }else{
                    Resp.fail(ret.get("Message"));
                }
            }
        } catch (ClientException e) {
            log.error("短信发送错误",e);
            Resp.fail("短信发送错误:"+e.getErrMsg());
        }
    }
    /**
     * @param signName      阿里云短信签名名称
     * @param phoneNumber   手机号
     * @param templateCode  短信模板代码
     * @param templateParam 模板值
     */
    public void sendMessage(String signName, String phoneNumber, String templateCode, Object templateParam) {
        String templateParamStr = JSONUtil.toJSONString(templateParam);
        log.info("sendMessage:准备发送:phoneNumber:{}:templateCode:{}:templateParam:{}", phoneNumber, templateCode, templateParamStr);
        boolean mobile = Validator.isMobile(phoneNumber);
        if (!mobile) {
            Resp.fail("手机号码格式有误!");
        }
        if(StringUtil.isEmpty(templateCode)){
            Resp.fail("系统配置错误!");
        }
        SmsMessage message = new SmsMessage();
        message.setCreateTime(new Date());
        UserInfo userInfo = Current.user(false);
        if (userInfo == null) {
            message.setCreateUser(phoneNumber);
        } else {
            message.setCreateUser(userInfo.getUsername());
        }
        message.setPhoneNumber(phoneNumber);
        message.setSignName(signName);
        message.setTemplateCode(templateCode);
        message.setTemplateParam(templateParamStr);

        //模拟发送，并不会真的发送
        if (SmsConfigs.mock.value().asBoolean()) {
            message.setStatus("模拟");
            dao.save(message);
            return;
        }
        /**
        Client client = null;
        try {
            client = createClient();
        } catch (Exception e) {
            e.printStackTrace();
            Resp.fail(e.getMessage());
        }

        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(phoneNumber)
                .setSignName(signName)
                .setTemplateCode(templateCode)
                .setTemplateParam(templateParamStr);
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = null;
        try {
            sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
        } catch (Exception e) {
           // e.printStackTrace();
            log.error("短信发送失败",e);
            message.setStatus("失败");
            message.setMemo(e.getMessage());
            dao.save(message);
            Resp.fail(e.getMessage());
        }
        if (!"ok".equalsIgnoreCase(sendSmsResponse.body.code)) {
            //错误code文档:https://help.aliyun.com/document_detail/101346.html?spm=api-workbench.API%20Explorer.0.0.1d3b6aa2EfsI8V
            log.error("sendSmsResponse.body.code:" + sendSmsResponse.body.code);
            message.setStatus("失败");
            message.setMemo(sendSmsResponse.body.code + ":" + sendSmsResponse.body.message);
            dao.save(message);
            Resp.fail(sendSmsResponse.body.message);
        }
         **/
        Map<String,String> params=new HashMap<>();
        params.put("PhoneNumbers", phoneNumber);
        params.put("SignName", signName);
        params.put("TemplateCode", templateCode);
        params.put("TemplateParam", templateParamStr);
        Map<String,String> ret=new HashMap<>();
        try {
           // sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
            String response=send("SendSms",params);
             ret= JSONUtil.parseObject(response);
        } catch (Exception e) {
            // e.printStackTrace();
            log.error("短信发送失败",e);
            message.setStatus("失败");
            message.setMemo(e.getMessage());
            dao.save(message);
            Resp.fail(e.getMessage());
        }
        if (!"OK".equalsIgnoreCase(ret.get("Code"))) {
            //错误code文档:https://help.aliyun.com/document_detail/101346.html?spm=api-workbench.API%20Explorer.0.0.1d3b6aa2EfsI8V
            log.error("sendSmsResponse.body.code:" + ret.get("Code"));
            message.setStatus("失败");
            message.setMemo(ret.get("Code") + ":" + ret.get("Message"));
            dao.save(message);
            Resp.fail(ret.get("Message"));
        }
        message.setStatus("成功");
        dao.save(message);
        log.info("sendMessage:发送成功:phoneNumber:{}:templateCode:{}:templateParam:{}", phoneNumber, templateCode, templateParam);
    }
    private String send(String action,Map<String,String> params){
        DefaultProfile profile=DefaultProfile.getProfile("cn-hangzhou", SmsConfigs.accessKeyId.strValue(),SmsConfigs.accessKeySecret.strValue());
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");

        request.setSysAction(action);
        for(Map.Entry<String,String> entry:params.entrySet()){
            request.putQueryParameter(entry.getKey(),entry.getValue());
        }
        try{
            CommonResponse response = client.getCommonResponse(request);
            return response.getData();
        } catch (ClientException e) {
            log.error(action,e);
        }
        return null;
    }
    public Page getSignList(){
        Map<String,String> params=new HashMap<>();
        params.put("PageIndex","1");
        params.put("PageSize","50");
        String signs= send("QuerySmsSignList",params);

        AcsPageResult signResult=JSONUtil.parseObject(signs, SignResult.class);
        return getPage(signResult);
    }

    public Page getTemplateList(){
        Map<String,String> params=new HashMap<>();
        params.put("PageIndex","1");
        params.put("PageSize","50");
        String templates= send("QuerySmsTemplateList",params);
        AcsPageResult signResult=JSONUtil.parseObject(templates, TemplateResult.class);
        return getPage(signResult);
    }

    private Page getPage(AcsPageResult signResult) {
        if(!"OK".equals(signResult.getCode())){
            Resp.fail("获取失败:"+signResult.getMessage());
        }
        List<Map> data=new ArrayList<>();
        for(Map<String,?> m:signResult.getData()){
            if("AUDIT_STATE_PASS".equals(m.get("AuditStatus"))){
                data.add(m);
            }
        }
        Page page = new Page(data,signResult.getTotalCount(),signResult.getPageSize(),signResult.getCurrentPage());
        return page;
    }

    @Data
    public static class TemplateResult extends AcsPageResult{
        @JsonProperty("SmsTemplateList")
        List<Map> data;
    }
    @Data
    public static class SignResult extends AcsPageResult{
        @JsonProperty("SmsSignList")
        List<Map> data;
    }
    @Data
    public abstract static class AcsPageResult{
        @JsonProperty("RequestId")
        String requestId;
        @JsonProperty("Message")
        String message;
        @JsonProperty("Code")
        String code;
        @JsonProperty("TotalCount")
        int totalCount;
        @JsonProperty("PageSize")
        int pageSize;
        @JsonProperty("CurrentPage")
        int currentPage;
        abstract List<Map> getData();
    }
}
